package net.sf.rose.business.bean.database;

import java.util.Date;

import net.sf.rose.util.DateFormat;

import org.apache.commons.lang.StringUtils;

/**
 * @author fengjian
 * @since 2014-6-17
 */
public class KeyGenerator {

	/** 日期格式化类 */
	private DateFormat dateFormat = null;

	/** 记数器值缓存 */
	private int count = 0;

	/** 日期值缓存 */
	private String day = null;

	/** 主键格式类型 */
	private char[] type = null;

	/** 主键格式字符串 */
	private String[] pattern = null;
	
	/** 记数器值缓存 */
	private boolean needInitialCount = true;

	/**
	 * 是否需要初始化计数器
	 */
	public boolean isNeedInitialCount() {
		return needInitialCount;
	}

	/**
	 * 生成主键 {yyyyMMdd}+[0001]+(****)+EN(日期必须在有序数字前)
	 * @param format  - 主键格式
	 */
	public void setkeyGenerateString(String format) {
		String[] arr = StringUtils.split(format, '+');
		type = new char[arr.length];
		pattern = new String[arr.length];
		for (int i = 0; i < arr.length; i++) {
			char c = arr[i].charAt(0);
			// 日期格式
			if (c == '{') {
				type[i] = 't';
				pattern[i] = arr[i].substring(1, arr[i].length() - 1);
				dateFormat = new DateFormat(pattern[i]);
			}
			// 有序数字
			else if (c == '[') {
				type[i] = 's';
				pattern[i] = arr[i].substring(1, arr[i].length() - 1);
				pattern[i] = "0000000000".substring(0, pattern[i].length());
			}
			// 无序数字
			else if (c == '(') {
				type[i] = 'd';
				pattern[i] = arr[i].substring(1, arr[i].length() - 1);
				pattern[i] = "1000000000".substring(0, pattern[i].length());
				needInitialCount = false;
			}
			// 字符
			else {
				type[i] = 'c';
				pattern[i] = arr[i];
			}
		}
	}

	/**
	 * 生成主键
	 * @return - 主键
	 */
	public synchronized String getUID() {
		String thisDay = null;
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < type.length; i++) {
			char c = type[i];
			// 日期格式
			if (c == 't') {
				thisDay = dateFormat.format(new Date());
				buf.append(thisDay);
			}
			// 有序数字
			else if (c == 's') {
				// 如果日期存在
				if (day != null) {
					// 如果当前日期与缓存日期一致，计数器累计
					if (thisDay.equals(day)) {
						count++;
					}
					// 如果不一致，重新计算
					else {
						count = 1;
					}
				}
				// 如果日期不存在，重新计算
				else {
					count++;
				}
				String str = pattern[i] + count;
				buf.append(str.substring(str.length() - pattern[i].length(), str.length()));
			}
			// 无序数字
			else if (c == 'd') {
				buf.append(((int) ((Math.random() * 9 + 1) * Integer.parseInt(pattern[i]))));
			}
			// 字符
			else {
				buf.append(pattern[i]);
			}
		}
		// 将当前日期缓存
		this.day = thisDay;
		return buf.toString();
	}

	/**
	 * 设置有序数字初始值
	 */
	public void initialCount(String format) {
		int s1 = 0, e1 = 0, s2 = 0, e2 = 0;
		boolean flag = false;
		// 从格式中取日期值
		for (int i = 0; i < type.length; i++) {
			// 日期格式
			if (type[i] == 't') {
				if (flag) {
					s1 = e2;
				}
				flag = true;
				e1 = s1 + pattern[i].length();
			} else {
				// 有序数字
				if (type[i] == 's') {
					if (flag) {
						s2 = e1;
					} else {
						s2 = s1;
					}
					flag = true;
					e2 = s2 + pattern[i].length();
				} else {
					s1 = s1 + pattern[i].length();
				}
			}
		}
		if (s1 != 0 && s1 != e1) {
			String maxDay = format.substring(s1, e1);
			String thisDay = dateFormat.format(new Date());
			if (maxDay.equals(thisDay)) {
				String str = format.substring(s2, e2);
				this.count = Integer.parseInt(str);
			}
		}
	}

	/**
	 * 设置有序数字减1
	 */
	public void backCount() {
		this.count = this.count > 1 ? this.count - 1 : 0;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		String type = "EN+{yyyyMMdd}+[0001]+(****)";
		KeyGenerator key = new KeyGenerator();
		key.setkeyGenerateString(type);
		//System.out.println(key.getUID());
		//System.out.println(key.getUID());
		type = "EN+{yyyyMMdd}+[01]";
		key.setkeyGenerateString(type);
		System.out.println(key.getUID());
		key.initialCount("EN2014071110");
		System.out.println(key.getUID());
	}
}
